###由用户输入的密码生成器到此差不多完结了，下面我们来编写由电脑随机生成的符合密码要求限制的密码生成器
#版本更新1：自动密码生成器，设计时就做到函数化，利用string和random标准库
#版本更新2：输出生成的正确的密码，并利用函数的参数来去掉验证信息。random(seed randint sample) join
#版本更新3：通过增加字符集合的内容，让生成的密码中元素可以重复，用string.printable 来代替那一长串字符集的设置
#bug修复：用切片，去掉string.printable中的后几位不可见字符

#上一个版本中，因为sample函数的显示，输出的密码是不能重复的，但是我们可以要求密码进行重复。
                #如何改进呢？改进sample吗？不，那个太麻烦了，直接改字符集合，让字符集合中本身就可以有重复的字符，
                                                                       #就可以了


#设计思路，之前，我们对程序进行了封装（包括函数化），因此，在我们要设计新的函数的时候，我们可以直接利用原来写好的函数
                                                                   #yanzheng_password(password):
        #同时，我们可以依照之前（对主函数也进行函数化来消除全局变量的方式），对要设计的这个新程序，也设计成一个
        #与原来主函数平行的主函数（在设计的时候，就做到程序的函数化封装）

import string
import random

def yanzheng_password(password,show_info):
    result = False

    password_state = 0b00000

    for char in password:
        if char.isupper():
            password_state = password_state | 0b10000
        elif char.islower():
            password_state |= 0b01000
        elif char.isdigit():
            password_state |= 0b00100
        else:
            password_state |= 0b00010
    if len(password) >= 8:
        password_state |= 0b00001

    #todo:输出反馈：

    if password_state == 0b11111:
        if show_info:
            print('密码符合要求！')

        result = True

    else:
        if show_info:
            tishi = '密码不符合要求，'
            if password_state & 0b00001 == 0:
                tishi = tishi + '长度不足8，'
            if password_state & 0b10000 == 0:
                tishi = tishi + '没有包含大写字符，'
            if password_state & 0b01000 == 0:
                tishi += '没有包含小写字符，'
            if password_state & 0b00100 == 0:
                tishi += '没有包含数字，'
            if password_state & 0b00010 == 0:
                tishi += '没有包含标点,'

            tishi = tishi[:-1]

            print(tishi)


    return (result)


def main_userimput():
    while 1:

        #TODO:用户输入密码
        user_password = input('请输入密码:')

        #TODO：判断密码的合法性(只是判断)

        if yanzheng_password(user_password):
            break

def generate_password():           #随机生成密码的函数
    #如何设计呢？首先去查找标准库里有没有可以使用的函数
    #于是我们找到，random 生成伪随机数的 函数库
    #其中有一个函数 random.sample(a,k=?) a : 代表字符集    k=? : (代表从字符集中随机抽取多少位的元素）
    #字符集a的设置，可以用最原始的方式，把集合中的所有元素都列出来
                  #但根据之前的经验，我们知道string库中有可以表示数字，大小写字母，符号的函数，所以我们直接采用
                                                 #string函数库
     #all_char_set = (string.ascii_uppercase + string.ascii_lowercase
     #               + string.digits + string.punctuation)
    all_char_set = string.printable[:-6]
    #改动字符集合，以让之达到可以密码之中元素可以重复的条件
    #all_char_set = all_char_set * 9 #还可以改进，用下面这一行的写法
    all_char_set *= 9
    result = ''.join(random.sample(all_char_set,k=9))
    return (result)


def mian_generate():
    while 1:

        #TODO:电脑来随机生成密码
        user_password = generate_password()      #

        #TODO：判断密码的合法性(只是判断)

        if yanzheng_password(user_password,show_info=False):
            ###要输出，符合要求的密码
             ##引入 f字符串的使用
            print(f"新生成的密码为：{user_password}")
            break

#main_userimput()
mian_generate()

#对random库中函数的介绍：
#random.seed(1) 其作用是：设立一个种子，使得产生的随机数是一样的，方便复现
#random.randint(1,100) randint(a,b) 从范围（a,b）内，产生一个伪随机数
#输出结果：35（比如） 则再次运行，随机数还是35，因为seed的作用
                    #若是没有seed，则随机数每次运行大致都不相同
    #若要改变随机数的值，则改变相应seed里边的参数值
#random.seed(2)
#random.randint(1,100)
#输出结果：25（比如） 则此随机数就固定在25了，方便某些特殊情况下，对实验结果的复现

#random.sample("123qweQWE",k=5)   sample("一个集合“，k=你想要的结果的长度)
                           #可以实现，从某一集合中，随机出来一个可以选定长度的列表（注意，是列表），且列表内的元素是不重复的
                                                           #也可以说，只会采用一次集合中的元素


